package com.lxl.xm.controller;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.excel.EasyExcel;
import com.arcsoft.face.toolkit.ImageFactory;
import com.arcsoft.face.toolkit.ImageInfo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.lxl.xm.exception.BusinessException;
import com.lxl.xm.mapper.StudentMapper;
import com.lxl.xm.model.dto.student.StudentAddRequest;
import com.lxl.xm.model.dto.student.StudentEnableRequest;
import com.lxl.xm.model.dto.student.StudentQueryRequest;
import com.lxl.xm.model.dto.student.ValidateStudent;
import com.lxl.xm.model.entity.Student;
import com.lxl.xm.model.enums.StudentRegisterEnum;
import com.lxl.xm.model.vo.StudentVO;
import com.lxl.xm.service.FaceEngineService;
import com.lxl.xm.service.StudentService;
import com.lxl.xm.common.*;
import com.lxl.xm.service.StudentUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/student")
@Slf4j
public class StudentController {

    @Resource
    StudentService studentService;

    @Resource
    FaceEngineService faceEngineService;

    @Resource
    StudentUserService studentUserService;

    @Resource
    StudentMapper studentMapper;

    /**
     * 分页获取学生列表
     *
     * @param studentQueryRequest
     * @param request
     * @return
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<StudentVO>> listStudentByPage(StudentQueryRequest studentQueryRequest, HttpServletRequest request) {
        long current = 1;
        long size = 10;
        Student studentQuery = new Student();
        if (studentQueryRequest != null) {
            BeanUtils.copyProperties(studentQueryRequest, studentQuery);
            current = studentQueryRequest.getCurrent();
            size = studentQueryRequest.getPageSize();
        }
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>(studentQuery);
        Page<Student> studentPage = studentService.page(new Page<>(current, size), queryWrapper);
        Page<StudentVO> studentVOPage = new PageDTO<>(studentPage.getCurrent(), studentPage.getSize(), studentPage.getTotal());
        List<StudentVO> studentVOList = studentPage.getRecords().stream().map(student -> {
            StudentVO studentVO = new StudentVO();
            BeanUtils.copyProperties(student, studentVO);
            return studentVO;
        }).collect(Collectors.toList());
        studentVOPage.setRecords(studentVOList);
        return ResultUtils.success(studentVOPage);
    }

    /**
     * 添加学生
     *
     * @param studentAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Long> addStudent(@RequestBody StudentAddRequest studentAddRequest, HttpServletRequest request) {
        if (studentAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Student student = new Student();
        BeanUtils.copyProperties(studentAddRequest, student);
        //解析图片添加人脸特征到数据库
        if (student.getPhoto() != null){
            //图片操作
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<byte[]> responseEntity
                    = restTemplate.getForEntity("http://tuchuang.yxihui.cn/OIPC.jpg", byte[].class);
            byte[] imageData = responseEntity.getBody();
            String s = Base64.getEncoder().encodeToString(imageData);
            //解析成人脸特征
            byte[] decode = cn.hutool.core.codec.Base64.decode(s);
            ImageInfo imageInfo = ImageFactory.getRGBData(decode);
            //人脸特征获取
            try {
                byte[] bytes = faceEngineService.extractFaceFeature(imageInfo);
                student.setFaceFeature(bytes);
                student.setFaceId(RandomUtil.randomString(10));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
//        studentService.validStudent(student, true);
        boolean result = studentService.save(student);
        // 抛异常
        if (!result){
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"添加失败");
        }
        long newStudentId = student.getId();
        // 返回用户的id
        return ResultUtils.success(newStudentId);
    }

    /**
     * 学生注册
     * @param idRequest
     * @return
     */
    @PostMapping("/register")
    public BaseResponse<Boolean> registerStudent(@RequestBody IdRequest idRequest){
        if (idRequest == null || idRequest.getId() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //判断学生是否存在
        long studentId = idRequest.getId();
        Student oldStudent = studentService.getById(studentId);
        if (oldStudent == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        //存在则更新注册状态
        Student student = new Student();
        student.setId(studentId);
        //设置注册状态
        student.setIsRegister(StudentRegisterEnum.Register.getValue());
        boolean result = studentService.updateById(student);
        return ResultUtils.success(result);
    }

    /**
     * 删除学生
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteStudent(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean b = studentService.removeById(deleteRequest.getId());
        return ResultUtils.success(b);
    }

    /**
     * 学生账号激活
     * @param studentEnableRequest
     * @return
     */
    @PostMapping("/enable")
    public BaseResponse<Boolean> enableStudent(@RequestBody StudentEnableRequest studentEnableRequest){
        if (studentEnableRequest == null || studentEnableRequest.getId() <= 0
                || studentEnableRequest.getAdmissionNoticeNumber() == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //判断学生是否存在
        long studentId = studentEnableRequest.getId();
        Student student = studentService.getById(studentId);
        if (student == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        //存在获取编号
        String admissionNoticeNumber = student.getAdmissionNoticeNumber();
        //编号错误
        if (!admissionNoticeNumber.equals(studentEnableRequest.getAdmissionNoticeNumber())){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Student newStudent = new Student();
        newStudent.setId(studentId);
        //设置注册状态
        newStudent.setIsRegister(StudentRegisterEnum.Register.getValue());
        boolean result = studentService.updateById(newStudent);
        return ResultUtils.success(result);
    }

    /**
     * 身份证，姓名，通知书编号验证
     * @param validateStudent
     * @return
     */
    @PostMapping("/validate")
    @Transactional
    public BaseResponse<Boolean> validateStudentByIdCardAndNameAndNoticeNumber
            (@RequestBody ValidateStudent validateStudent){
        if (validateStudent == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"学生信息有误");
        }
        String identityCardNumber = validateStudent.getIdentityCardNumber();
        String name = validateStudent.getName();
        String admissionNoticeNumber = validateStudent.getAdmissionNoticeNumber();
        if (StringUtils.isAnyBlank(identityCardNumber,name,admissionNoticeNumber)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"学生信息有误");
        }
        Boolean b = studentService.validateStudentByIdCardAndNameAndNoticeNumber(validateStudent);
        //如果验证成功
        if (b){
            //查出学生
            Student student = studentMapper.selectStudentByIdCard(identityCardNumber);
            //身份证后六位
            String password = identityCardNumber.substring(identityCardNumber.length() - 6);
            //向studentUser中插入数据
            studentUserService.insertStudentUser(student.getStudentNumber(),password);
            //注册
            student.setIsRegister(1);
            //注册时间
            student.setRegisterDate(new Date());
            //更新
            studentService.updateById(student);
        }
        //验证学生信息是否存在数据库并且未注册
        return ResultUtils.success(b);
    }

    /**
     * 以文件形式导入数据库
     * @param file 填有学生数据的xlsx文件
     * @return
     */
    @PostMapping("/upload")
    public BaseResponse<String> upload(MultipartFile file){
        try {
            EasyExcel.read(file.getInputStream(), StudentAddRequest.class,
                            new StudentUploadListener(studentService,faceEngineService))
                    .sheet().doRead();
        } catch (IOException e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"文件上传失败");
        }
        return ResultUtils.success("上传成功");
    }

    /**
     * 近七天注册的学生人数
     * @return
     */
    @GetMapping("/statistics/lastSevenDays")
    public BaseResponse<List<DailyRegistration>> getRegisteredStudentsLast7Days(){
        return ResultUtils.success(studentService.getRegisteredStudentsLast7Days());
    }

    /**
     * 注册学生的总人数
     * @return
     */
    @GetMapping("/statistics/total")
    public BaseResponse<Long> getTotalRegisteredStudents(){
        return ResultUtils.success(studentService.getTotalRegisteredStudents());
    }

    /**
     * 按省份统计学生的人数
     * @return
     */
    @GetMapping("/count/byProvince")
    public BaseResponse<List<Map<String, Object>>> countStudentsByProvince() {
        return ResultUtils.success(studentService.countStudentsByProvince());
    }

    /**
     * 按学院统计人数
     * @return
     */
    @GetMapping("/count/byCollege")
    public BaseResponse<List<Map<String,Object>>> countStudentsByCollege(){
        return ResultUtils.success(studentService.countStudentsByCollege());
    }


//    @GetMapping("/count/isRegister")
//    public BaseResponse<Long> countRegisteredStudent(){
//
//    }







}
